package de.argh.codebook.service.mock;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import de.argh.codebook.model.Article;
import de.argh.codebook.model.Coder;
import de.argh.codebook.model.PageState;
import de.argh.codebook.service.ArticleService;
import de.argh.codebook.service.CoderService;

@Service
public class ArticleServiceMock implements ArticleService {

  private static List<Article> articles;
  private static boolean prepared = false;

  @Inject
  private CoderService coderService;

  private static String bodyText =
      "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, " +
          "sed diam nonumy eirmod tempor invidunt ut labore et dolore " +
          "magna aliquyam erat, sed diam voluptua. At vero eos et accusam " +
          "et justo duo dolores et ea rebum. Stet clita kasd gubergren.";

  static {
    init();
  }

  private static void init() {
    articles = new ArrayList<Article>();

    for (int i = 1; i <= 20; i++) {
      List<Article> comments = new ArrayList<Article>();

      for (int m = 100; m <= 500; m += 100) {
        comments.add(createArticle(Long.valueOf(m + i), null));
      }
      articles.add(createArticle(Long.valueOf(i), comments));
    }
  }

  public Article getArticleById(Long id) {
    prepareArticlesWithAuthor();
    
    for (Article article : articles) {
      if (article.getId().equals(id)) {
        return article;
      }
    }
    return null;
  }

  public List<Article> getCommentsForArticle(Long id) {
    prepareArticlesWithAuthor();
    
    List<Article> comments = new ArrayList<Article>();
    Article article = getArticleById(id);
    if (article != null) {
      for (Article comment : article.getComments()) {
        comments.add(comment);
      }
    }
    return comments;
  }

  public List<Article> getArticelOverview(Long coderId, PageState pageState) {
    prepareArticlesWithAuthor();
    
    Long start = pageState.getPage() * pageState.getSize();
    Long end = start + pageState.getSize();

    Coder coder = coderService.getCoderById(coderId);
    coder.setArticles(getArticlesFromCoder(coder.getId()));
    List<Article> overviewArticles = new ArrayList<Article>();

    overviewArticles.addAll(coder.getArticles());
    for (Coder follower : coder.getFollower()) {
      follower.setArticles(getArticlesFromCoder(follower.getId()));
      overviewArticles.addAll(follower.getArticles());
    }

    List<Article> overview = new ArrayList<Article>();
    for (Long i = Long.valueOf(1); i <= overviewArticles.size(); i++) {
      if (i >= start && i <= end) {
        overview.add(overviewArticles.get((int) (i - 1)));
      }
    }

    return overview;
  }

  @Override
  public List<Article> getArticlesFromCoder(Long coderId) {
    prepareArticlesWithAuthor();
    
    List<Article> articlesFromCoder = new ArrayList<Article>();
    for (Article article : articles) {
      if (article.getAuthor().getId().equals(coderId)) {
        articlesFromCoder.add(article);
      }
    }
    return articlesFromCoder;
  }

  @Override
  public void deleteArticle(Long id) {
    // TODO Auto-generated method stub

  }

  /**
   * Creates an fake article.
   * 
   * @param id
   * @return
   */
  private static Article createArticle(Long id, List<Article> comments) {
    Article article = new Article();

    article.setId(id);
    article.setTitle("Title " + id);
    article.setBody(bodyText);
    article.setLastModified(new Date());

    if (comments != null) {
      article.getComments().addAll(comments);
    }

    return article;
  }

  private void prepareArticlesWithAuthor() {
    if (!prepared) {
      for (Article article : articles) {
        article.setAuthor(coderService.getCoderById(article.getId() % 10 + 1));
        for (Article comment : article.getComments()) {
          comment.setAuthor(coderService.getCoderById(comment.getId() % 10 + 1));
        }
      }
      prepared = true;
    }
  }

}
